/*
 * TcpClient.cpp
 *
 *   Created on: 2010-1-29     
 *  Description: 
 *    Copyright: 2010 @ ICT Li Heyuan
 */

#include "../../include/client/TcpClient.h"
#include "../../include/json_cpp/value.h"
#include "../../include/json_cpp/reader.h"
#include "../../include/json_cpp/writer.h"
#include "../../include/util/JsonRpcException.h"
using Json::Reader;
using Json::FastWriter;

#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;

bool TcpClient::_notification(const string &sendBuf, unsigned int timeout /*=
 3*/)
{

	int sock = -1;
	try
	{
		sock = Network::socket();

		//创建sock，设置超时，非阻塞
		//Network::setNonBlocking(sock);
		Network::setTimeOut(sock, timeout);

		//连接
		if (!Network::connect(sock, _serverAddr))
		{
			//连接失败
			throw "send() on sock fail.";
		}
		else
		{
			unsigned long nLeft; //是否eof,发送剩下多少字节

			nLeft = sendBuf.size();
			while (nLeft)
			{
				if (!Network::sendBytes(sock, sendBuf, nLeft))
				{
					//发送出错
					Network::close(sock);
					return false;
				}
			}

			//接收
			string recvBuf;//接受数据的缓冲区
			bool eof = false;
			while (!eof)
			{
				if (!Network::recvBytes(sock, recvBuf, eof))
				{
					throw "recv() on sock fail.";
				}
			}

			//notification，返回应该为空
			if (recvBuf.empty())
			{
				return true;
			}
			else
			{
				return false;
			}

		}//end connect success
	} catch (...)
	{
		//出错
		Network::close(sock);
		return false;
	}

}

bool TcpClient::_call(const string &sendBuf, Json::Value &result,
		unsigned int timeout /*=
 3*/)
{

	int sock = -1;
	try
	{
		sock = Network::socket();

		//创建sock，设置超时，非阻塞
		//Network::setNonBlocking(sock);
		Network::setTimeOut(sock, timeout);

		//连接
		if (!Network::connect(sock, _serverAddr))
		{
			//连接失败
			throw JsonRpcException("connect fail.");
		}
		else
		{
			//发送数据
			unsigned long nLeft; //是否eof,发送剩下多少字节
			nLeft = sendBuf.size();
			while (nLeft)
			{
				if (!Network::sendBytes(sock, sendBuf, nLeft))
				{
					//发送出错
					throw JsonRpcException("send() on sock fail.");
				}
			}

			//接收string recvBuf;//发送、接受数据的缓冲区
			bool eof = false;
			string recvBuf;
			while (!eof)
			{
				if (!Network::recvBytes(sock, recvBuf, eof))
				{
					throw JsonRpcException("recv() on sock fail.");
				}
			}

			//把结果转化为Json
			Reader reader;
			Value tmp;
			if (!reader.parse(recvBuf, tmp))
			{
				throw JsonRpcException("parse result fail.");
			}
			else
			{
				Network::close(sock);
				if (tmp["error"] == Json::nullValue)
				{
					result = tmp["result"];
					return true;
				}
				else
				{
					result = tmp["error"];
					return false;
				}
			}
		}//end connect success
	} catch (JsonRpcException &exception)
	{
		Network::close(sock);
		result = exception.what();
		return false;
	} catch (...)
	{
		//出错
		Network::close(sock);
		result = "unknown error.";
		return false;
	}

}
